<template>
  <a-layout-content>
    <a-table
      :columns="state.cols"
      :data-source="lstDisplay"
      bordered
      size="small"
      :pagination="false"
      :scroll="tableScroll"
      :row-selection="rowSelection"
    >
      <template #bodyCell="{ column, record }">
        <template v-if="column.dataIndex == '#'">
          <a href="#RecordDetail" @click="goRecordDetail(record)">{{
            record[column.dataIndex]
          }}</a>
        </template>
        <template v-if="column.multi">
          <a-button
            v-if="record[column.dataIndex]"
            type="link"
            @click="goViewMultiFieldValues(record, column)"
            ><EllipsisOutlined
          /></a-button>
        </template>
        <template v-if="column.type == 'FtBool'">
          <a-checkbox
            v-model:checked="record[column.dataIndex]"
            disabled
          ></a-checkbox>
        </template>
        <template v-if="column.type == 'FtModel'">
          <span>{{ record[column.dataIndex] }}</span>
        </template>
        <template v-if="column.type == 'FtFile'">
          <FileDisplayer
            :file-key="record[column.dataIndex + 'fkey']"
            :file-name="record[column.dataIndex + 'fname']"
          ></FileDisplayer>
        </template>
        <template v-if="column.type == 'FtJson'">
          <a-button
            v-if="record[column.dataIndex]"
            @click="goViewJson(record, column)"
            ><EllipsisOutlined
          /></a-button>
        </template>
        <template v-if="column.type == 'FtYaml'">
          <a-button
            v-if="record[column.dataIndex]"
            @click="goViewYaml(record, column)"
            ><EllipsisOutlined />
          </a-button>
        </template>
        <!-- <template v-if="column.type == 'EncryptedB64'">
        <a-button v-if="record[column.dataIndex]" shape="circle"
          ><UnlockOutlined
        /></a-button>
      </template> -->
        <template v-if="column.dataIndex === 'operate'">
          <a-button
            size="small"
            v-if="record['11']"
            :title="$t('223')"
            type="link"
            @click="modifyRecord(record)"
            ><EditOutlined></EditOutlined>
          </a-button>
          <a-button
            size="small"
            v-if="record['12'] && props.shareMode"
            :title="$t('223')"
            type="link"
            danger
            @click="deleteRecord(record)"
            ><DeleteOutlined></DeleteOutlined>
          </a-button>
        </template>
      </template>
    </a-table>
    <div style="text-align: center">
      <a-button
        type="primary"
        @click="loadMore"
        :disabled="!state.hasMoreRecords"
        >{{ $t("379") }}</a-button
      >
    </div>
    <a-modal
      v-model:open="state.popMultiValues"
      :footer="null"
      :title="$t('380')"
      width="720px"
    >
      <a-list bordered :data-source="state.selectedFieldValue">
        <template #renderItem="{ item }">
          <a-list-item>
            <pre>{{ item }}</pre>
          </a-list-item>
        </template>
      </a-list>
    </a-modal>
    <a-modal
      v-model:open="state.popJsonValue"
      :footer="null"
      :title="$t('380')"
      width="720px"
    >
      <JsonEditor
        :canEdit="false"
        v-model="state.selectedFieldValue"
      ></JsonEditor>
    </a-modal>
    <a-modal
      v-model:open="state.popYamlValue"
      :footer="null"
      :title="$t('380')"
      width="720px"
    >
      <YamlEditor
        :canEdit="false"
        v-model="state.selectedFieldValue"
      ></YamlEditor>
    </a-modal>
    <a-drawer
      v-model:open="state.popDetailView"
      :title="$t('381')"
      size="large"
      :bodyStyle="{ padding: '4px' }"
      :headerstyle="{ padding: '4px' }"
    >
      <RecordDetailViewer
        ref="refRdv"
        :fields="appStore.allModelFieldMap.get(channel.selectedModel.id)"
        :recordd="channel.recordInEditting"
      ></RecordDetailViewer>
    </a-drawer>
  </a-layout-content>
</template>
<script setup>
import { computed, onBeforeMount, reactive, ref } from "vue";
import CommonDefine from "@/component/CommonDefine";
import Utils from "@/component/Utils";
import {
  EditOutlined,
  EllipsisOutlined,
  DeleteOutlined,
} from "@ant-design/icons-vue";
import RecordDetailViewer from "@/component/record/RecordDetailViewer.vue";
import JsonEditor from "@/component/field/JsonEditor.vue";
import YamlEditor from "@/component/field/YamlEditor.vue";
import FileDisplayer from "@/component/field/FileDisplayer.vue";

const props = defineProps({
  shareMode: { type: Boolean, default: false },
  filter: String,
  apiFilters: Object,
});
const emits = defineEmits(["modify", "select"]);
const appStore = CommonDefine.appStore();
const channel = CommonDefine.channel();
const lstModelRecordd = reactive([]);
const lstDisplay = reactive([]); //因为前端表格展示不支持.语法，弄一个专门放display的对象数组
const state = reactive({
  pageIndex: 0,
  hasMoreRecords: false,
  lastIndex: 0,
  cols: [],
  popMultiValues: false,
  popDetailView: false,
  popJsonValue: false,
  popYamlValue: false,
  selectedFieldValue: [],
  selectedRowKeys: [],
});
const tableScroll = computed(() => {
  return { y: document.documentElement.clientHeight - 132 };
});

const loadCols = () => {
  // console.log(channel.selectedVisitRequest);
  CommonDefine.clearArray(state.cols);
  state.cols.push({ dataIndex: "#", title: "#", width: 80, align: "right" });
  let sortableFt = [
    "FtString",
    "FtInt",
    "FtFloat",
    "FtAutoIncreaseInt",
    "FtAutoIncreaseIntGlobal",
    "FtDate",
    "FtTime",
    "FtDateTime",
    "FtCode",
  ];
  CommonDefine.runWithFieldCache(channel.selectedModel.id, (fields) => {
    fields.forEach((field, index) => {
      // 暂时性的处理，表列只展示3个字段，更多字段在详情中展示
      if (index > 2) {
        return;
      }
      // 排序
      let col = {
        dataIndex: field.id,
        title: field.label,
        type: field.fieldType.T,
        multi: field.multi,
        ellipsis: true,
      };
      // 有单位，加上单位展示
      if (
        CommonDefine.useful(field.fieldType.C) &&
        CommonDefine.useful(field.fieldType.C.unitLabel)
      ) {
        col.title += "(" + field.fieldType.C.unitLabel + ")";
      }
      if (sortableFt.indexOf(field.fieldType.T) > -1 && !field.multi) {
        col.sorter = (a, b) => {
          return a[field.id].localeCompare(b[field.id], "zh");
        };
        col.sortDirections = ["descend", "ascend"];
      }
      // 是否是加密字段
      // if (props.shareMode && CommonDefine.useful(channel.visitToken)) {
      //   let vg = channel.visitToken.vg;
      //   if (CommonDefine.usefulArray(vg.ruleF)) {
      //     vg.ruleF.forEach((limit) => {
      //       if (limit.T == "SrfEnc" && limit.C.indexOf(field.id) > -1) {
      //         col.type = "EncryptedB64";
      //       }
      //     });
      //   }
      // }
      state.cols.push(col);
    });
    state.cols.push({
      dataIndex: "operate",
      title: "",
      width: 96,
    });
  });
};

// 填充rec.display属性
const _recArrayToDisplayArray = () => {
  CommonDefine.clearArray(lstDisplay);
  lstModelRecordd.forEach((rec, index) => {
    // 不能改动查询结果列表，以免再次渲染出错， 可以优化，不清空listdisplay，从record某个偏移量开始渲染
    let display = Object.assign({}, rec.display);
    // 转换user id 为 user name
    if (display["2"] != undefined) {
      display["2"] = Utils.getUserName(display["2"]);
    }
    display["#"] = index + 1;
    // 字符串化的bool值影响展示
    Object.keys(display).forEach((x) => {
      if (display[x] == "true" || display[x] == "false") {
        display[x] = JSON.parse(display[x]);
      }
    });
    display["key"] = rec.meta.id;
    lstDisplay.push(display);
  });
};

const _do_fetch = () => {
  let pd = {
    pageIndex: state.pageIndex,
    pageSize: 100,
    modelId: channel.selectedModel.id,
    lastIndex: state.lastIndex,
    filters: props.apiFilters,
    newToOld: channel.selectedOrder == "new_to_old",
  };
  let url = props.shareMode
    ? `/api/v1/record/share-page`
    : `/api/v1/record/page`;
  CommonDefine.apiPostArm(url, pd, (d) => {
    d.data.forEach((x) => {
      judgeActionRight(x);
      lstModelRecordd.push(x);
      // 为了文件展示组件可以使用，需要将文件的ID和文件名写入display对象，为了支持一个模型中的多个文件字段,属性key值中包含字段ID
      Object.entries(x.value).forEach(([key, value]) => {
        // console.log(key, value);
        if (value.T == "S401") {
          let k = key + "fkey";
          x.display[k] = value.C.v;
          k = key + "fname";
          x.display[k] = value.C.d;
        }
      });
    });
    _recArrayToDisplayArray();
    state.lastIndex = d.lastIndex;
    state.hasMoreRecords = d.data.length == pd.pageSize;
  });
};

const loadRecords = () => {
  CommonDefine.clearArray(lstModelRecordd);
  state.pageIndex = 1;
  state.lastIndex = 0;
  _do_fetch();
};

const loadMore = () => {
  state.pageIndex++;
  _do_fetch();
};

const modifyRecord = (display) => {
  let record = lstModelRecordd.find((item) => item.meta.id == display["key"]);
  channel.recordInEditting = record;
  emits("modify", record);
};

const _do_delete = (ids) => {
  CommonDefine.apiPostArm(
    "/api/v1/record/remove",
    {
      modelId: channel.selectedModel.id,
      recordIds: ids,
    },
    (d) => {
      ids.forEach((recordId) => {
        let idx = lstModelRecordd.findIndex((rdd) => rdd.meta.id == recordId);
        lstModelRecordd.splice(idx, 1);
      });
      _recArrayToDisplayArray();
    }
  );
};

// 组件内删除单条记录，用于共享访问时删除权限允许删除的记录
const deleteRecord = (display) => {
  _do_delete([display["key"]]);
};

const goViewMultiFieldValues = (valueMap, column) => {
  state.selectedFieldValue = JSON.parse(valueMap[column.dataIndex]);
  state.popMultiValues = true;
};

const goViewJson = (valueMap, column) => {
  state.selectedFieldValue = valueMap[column.dataIndex];
  state.popJsonValue = true;
};

const goViewYaml = (valueMap, column) => {
  state.selectedFieldValue = valueMap[column.dataIndex];
  state.popYamlValue = true;
};

const doSearch = () => {
  if (CommonDefine.isStringValue(props.filter)) {
    let filteredArray = lstDisplay.filter((item) => {
      let hit = false;
      for (const key in item) {
        if (parseInt(key) > 10000) {
          if (item[key].indexOf(props.filter) > -1) {
            hit = true;
            break;
          }
        }
      }
      return hit;
    });
    CommonDefine.clearArray(lstDisplay);
    filteredArray.forEach((item) => lstDisplay.push(item));
  } else {
    _recArrayToDisplayArray();
  }
};

const refRdv = ref();

// 弹出记录详细信息组件
const goRecordDetail = (valueMap) => {
  let recordd = lstModelRecordd.find((item) => item.meta.id == valueMap["0"]);
  // console.log(recordd);
  channel.recordInEditting = recordd;
  state.popDetailView = true;
};

// 判断一条记录有无修改部分或全部数据的权限
const judgeActionRight = (recordd) => {
  // 代理的模型不可修改
  if (CommonDefine.useful(channel.selectedModel.store)) {
    recordd.display["11"] = false;
    recordd.display["12"] = false;
    return;
  }
  // 自己的记录可以修改
  let commiter = recordd.meta.uid;
  if (commiter == localStorage.getItem("uid")) {
    recordd.display["11"] = true;
    recordd.display["12"] = true;
    return;
  }
  if (props.shareMode) {
    recordd.display["11"] = JSON.parse(recordd.display["11"]);
    recordd.display["12"] = JSON.parse(recordd.display["12"]);
  } else {
    recordd.display["11"] = true;
    recordd.display["12"] = true;
  }
};

const rowSelection = computed(() => {
  return {
    selectedRowKeys: state.selectedRowKeys,
    onChange: (eve) => {
      state.selectedRowKeys = eve;
      emits("select", eve);
    },
  };
});

// 组件外批量调用删除记录
const deleteRecords = () => {
  _do_delete(state.selectedRowKeys);
};

onBeforeMount(() => {
  loadCols();
});

defineExpose({ loadRecords, doSearch, deleteRecords });
</script>
